<template>
  <table :class="`ee-table${bordered ? ' ee-table-border' : ''}`">
    <slot name="head">
      <thead v-if="!headless">
        <th v-for="column in columns">
          <slot :name="`head-${column.key}`" :column="column">
            {{ column.label || column.key }}
          </slot>
        </th>
      </thead><template v-else />
    </slot>

    <tbody>
      <template v-if="datas?.length">
        <tr v-for="item, index in datas" :class="{ stripe: stripe && index % 2 != 0, clickable: !!onRowClick }"
          @click="onRowClick?.(item, index)" v-bind="getTrBind(item, index)">
          <td v-for="column in columns">
            <slot :name="column.key" :value="column.value ? column.value(item, index) : item[column.key]" :row="item"
              :column="column">
              {{ column.value ? column.value(item, index) : item[column.key] }}
            </slot>
          </td>
        </tr>
      </template>
      <template v-else>
        <tr>
          <td :colspan="columns?.length" class="empty">
            <slot>
              暂时没有数据
            </slot>
          </td>
        </tr>
      </template>
    </tbody>

    <tfoot v-if="$slots.foot">
      <slot name="foot" :datas="datas"></slot>
    </tfoot><template v-else />
  </table>
</template>

<script type="text/javascript">
// todo: 通用组件的检测可以参考 router-link，组件有提示，props 的 :to="{}" 也有提示

/** 表头定义
 * @template T
 * @typedef {object} column
 * @property {string} key - 字段名，也是显示数据的插槽的名字
 * @property {string} [label] - 表头标题，默认为 key
 * @property {(data: T, index:number) => any} [value] - 读取字段的值，默认根据字段名读取对象的值
 */

/** 数据表格 v1.0.0
 * @template T
 */
export default {
  name: "ee-table",
  __slots: {
    /** 自定义 thead 和 th，可用于复杂表头 */
    head: {
      /** props.columns 传入的数据
       * @type {column<T>[]} */
      columns: undefined,
    },
    /** 自定义表头列渲染 */
    headCol: {
      /** 当前列的表头信息
       * @type {column<T>}
       */
      column: undefined,
    },
    /** 自定义列数据渲染 */
    col: {
      /** 当前 td 的值 */
      value: undefined,
      /** 当前行的数据
       * @type {T}
       */
      row: undefined,
      /** 当前列的表头信息
       * @type {column<T>}
       */
      column: undefined,
    },
  },
  props: {
    /** 数据数组，元素必须是对象 */
    datas: {
      type: Array,
      /** @type {T[]} */
      default: undefined,
      required: true,

    },
    /** 数据列配置，默认为字段名作为列名 */
    columns: {
      type: [Object, Array],
      /** @type {column<T>[]} */
      default: undefined,
    },
    /** 是否显示斑马纹 */
    stripe: Boolean,
    /** 是否显示边框 */
    bordered: Boolean,
    /** 是否显示表头 */
    headless: Boolean,

    /** 表头绑定数据 */
    onTr: Function,

    onRowClick: Function,
  },
  computed: {
    // todo: columns 在没传入时，直接读取 datas 的字段作为表头
  },
  methods: {
    getTrBind(item, index) {
      const bind = this.onTr?.(item, index);
      if (bind?.class)
        bind[this.$.vnode.scopeId] = "";
      return bind;
    },
  },
}
</script>

<style lang="scss">
.ee-table {
  border-collapse: collapse;
  text-align: left;
  width: 100%;

  &.ee-table-border {

    th,
    tr,
    td {
      border: 1px solid var(--ee-table-border);
    }
  }

  th,
  td {
    padding: .5em;
    border-bottom: 1px solid var(--ee-table-border);
  }

  tr.stripe {
    background-color: var(--ee-table-stripe);
  }

  tr.clickable {
    cursor: pointer;
  }

  .empty {
    text-align: center;
    padding: 2em;
    color: var(--line0);
    border: none;
  }
}
</style>